package com.dartfar.mail.service;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;

import com.dartfar.base.dao.DaoUtil;
import com.dartfar.base.model.T_User;
import com.dartfar.base.service.BaseServiceImpl;
import com.dartfar.base.service.UserService;
import com.dartfar.mail.model.Attachment;
import com.dartfar.mail.model.Mail;
import com.dartfar.mail.model.MailState;
import com.dartfar.mail.model.SendState;

@Component("mailService")
public class MailServiceImpl extends BaseServiceImpl<Mail> implements MailService {

	private DaoUtil<Mail> mailDaoUtil;
	private DaoUtil<MailState> mailStateDaoUtil;
	private DaoUtil<SendState> sendStateDaoUtil;
	private DaoUtil<Attachment> attachmentDaoUtil;
	
	private UserService userService;
	private SendStateService sendStateService;
	private MailStateService mailStateService;
	//private DepartmentService departmentService;
	
	private static final int BUFFER_SIZE = 16 * 1024;
	
	private String fileStoreDir = "E:\\upload\\mail\\";
	
	
	@Override
	public void sendMail(int[] receiveIds, Mail mail) {
		// TODO Auto-generated method stub
		mailDaoUtil.save(mail);
		
		for (int id : receiveIds) {
			T_User receiveUser = userService.get(id);
			MailState ms = new MailState();
			ms.setMail(mail);
			ms.setReceiveDate(new Date());
			ms.setReceiveUser(receiveUser);
			ms.setReadFlag(UNREAD);
			mailStateDaoUtil.save(ms);
		}
	}

	@Override
	public void sendMail(int sendId, int[] receiveIds, Mail mail) {
		// TODO Auto-generated method stub
		mailDaoUtil.save(mail);
		T_User sendUser = userService.get(sendId);
		SendState ss = new SendState();
		ss.setMail(mail);
		ss.setSendDate(new Date());
		ss.setSendUser(sendUser);
		StringBuffer sb = new StringBuffer();
		for (int id : receiveIds) {
			T_User receiveUser = userService.get(sendId);
			sb.append(receiveUser.getPerson().getName()).append(" ");
			MailState ms = new MailState();
			ms.setMail(mail);
			ms.setReceiveDate(new Date(System.currentTimeMillis()));
			ms.setReceiveUser(receiveUser);
			ms.setSendUser(sendUser);
			ms.setReadFlag(UNREAD);
			mailStateDaoUtil.save(ms);
		}
		ss.setReceiveNames(sb.toString());
		sendStateDaoUtil.save(ss);
	}

	@Override
	public void sendMail(int sendId, String[] receiveIds, Mail mail) {
		// TODO Auto-generated method stub
		mailDaoUtil.save(mail);
		T_User sendUser = userService.get(sendId);
		SendState ss = new SendState();
		ss.setMail(mail);
		ss.setSendDate(new Date());
		ss.setSendUser(sendUser);
		StringBuffer sb = new StringBuffer();
		Set<T_User> receiveUsers = paseEmailAddress(receiveIds);
		for (T_User receiveUser : receiveUsers) {
			sb.append(receiveUser.getPerson().getName()).append(" ");
			MailState ms = new MailState();
			ms.setMail(mail);
			ms.setReceiveDate(new Date());
			ms.setReceiveUser(receiveUser);
			ms.setSendUser(sendUser);
			ms.setReadFlag(UNREAD);
			mailStateDaoUtil.save(ms);
		}
		ss.setReceiveNames(sb.toString());
		sendStateDaoUtil.save(ss);
	}

	private Set<T_User> paseEmailAddress(String[] receiveIds) {
		Set<T_User> ids = new HashSet<T_User>();
		for(String id : receiveIds){
			ids.add(userService.get(Integer.valueOf(id)));
		}
		
/*		for (String email : receiveIds) {
			if (email.contains("@user")) {
				ids.add(userService.getByName(paseEmailSuffx(email)));
			} else if (email.contains("@depart")) {
				Set<Person> ps = departmentService.getDepartmentByCode(paseEmailSuffx(email)).getPersons();
				for (Person p : ps) {
					ids.add(p.getUser());
				}
			} else if (email.contains("@post")) {
				Set<Person> ps = postDao.getPostByCode(paseEmailSuffx(email))
						.getPersons();
				for (Person p : ps) {
					ids.add(p.getUser());
				}
			}
		}*/
		return ids;
	}

/*	private String paseEmailSuffx(String email) {
		return email.substring(0, email.indexOf('@'));
	}*/
	
	@Override
	public List<MailState> receiveMail(int userid) {
		// TODO Auto-generated method stub
		return mailStateService.getMailListBySate(userid, UNREAD);
	}

	@Override
	public void removeReceiveMail(int id) {
		// TODO Auto-generated method stub
		MailState ms = mailStateDaoUtil.get(id, MailState.class);
		delReceiveMail(id, ms.getMail().getId());
	}

	private void delReceiveMail(int id, int mailid) {
		if (sendStateService.checkEmail(mailid)
				&& mailStateService.getMailReceiveCount(mailid) == 1) {
			mailStateDaoUtil.delete(mailStateDaoUtil.get(id, MailState.class));
			mailDaoUtil.delete(mailDaoUtil.get(mailid, Mail.class));
		} else {
			mailStateDaoUtil.delete(mailStateDaoUtil.get(id, MailState.class));
		}
	}
	
	@Override
	public List<MailState> getReceiveListByUserId(int userId) {
		// TODO Auto-generated method stub
		return mailStateService.getMailListByUserId(userId);
	}

	@Override
	public List<MailState> getReceiveListByUserIdByLimit(int userId, int limit) {
		// TODO Auto-generated method stub
		//return getMailStateDao().getReceiveListByUserIdByLimit(userId, limit);
		return null;
	}

	@Override
	public List<SendState> getSendListByUserId(int userId) {
		// TODO Auto-generated method stub
		return sendStateService.getSendListById(userId);
	}

	@Override
	public void removeSendMail(int id) {
		// TODO Auto-generated method stub
		SendState ss = sendStateDaoUtil.get(id, SendState.class);
		delSendMail(ss.getMail().getId(), id);
	}

	private void delSendMail(int mailid, int id) {
		if (mailStateService.getMailReceiveCount(mailid) == 0) {
			mailStateDaoUtil.delete(mailStateDaoUtil.get(id, MailState.class));
			removeMail(mailid);
		} else {
			sendStateDaoUtil.delete(sendStateDaoUtil.get(id, SendState.class));
		}
	}
	
	private void removeMail(int mailId){
		Mail mail = mailDaoUtil.get(mailId, Mail.class);
		if(mail.getAttachments().size()>0){
			for(Attachment att : mail.getAttachments()){
				String realpath = fileStoreDir + att.getPath();
				removeFile(realpath);
			}
		}
		mailDaoUtil.delete(mail);
	}
		
	@Override
	public void clearReceive(int userid) {
		// TODO Auto-generated method stub
		List<MailState> list = getReceiveListByUserId(userid);
		for (MailState m : list) {
			delReceiveMail(m.getId(), m.getMail().getId());
		}
	}

	@Override
	public void clearSend(int userid) {
		// TODO Auto-generated method stub
		List<SendState> list = getSendListByUserId(userid);
		for (SendState s : list) {
			delSendMail(s.getMail().getId(), s.getId());
		}
	}

	@Override
	public SendState getSendMail(int id) {
		// TODO Auto-generated method stub
		return sendStateDaoUtil.get(id, SendState.class);
	}

	@Override
	public MailState showReceiveMail(int id) {
		// TODO Auto-generated method stub
		MailState mailState = mailStateDaoUtil.get(id, MailState.class);
		if (mailState.getReadFlag() == UNREAD) {
			mailState.setReadFlag(READ);
		}
		return mailState;
	}

	@Override
	public Long getUnReadMailCount(int id) {
		// TODO Auto-generated method stub
		return mailStateService.getMailCountBySate(id, UNREAD);
	}

	@Override
	public void upload(Mail mail, File[] uploadFile, String[] caption,
			String[] uploadFilename) {
		// TODO Auto-generated method stub
		for(int i=0;i<uploadFile.length;i++){
			String nameSuffix = System.currentTimeMillis()+ getExtention(uploadFilename[i]);
			String realpath = fileStoreDir + nameSuffix;
			File dst = new File(realpath);
			copy(uploadFile[i], dst);
			Attachment att = new Attachment();
			att.setPath(nameSuffix);
			att.setFileName(uploadFilename[i]);
			att.setTitle(caption[i]);
			att.setMail(mail);
			attachmentDaoUtil.save(att);
		}
	}

	@Override
	public Attachment getAttachment(int attachId) {
		// TODO Auto-generated method stub
		return attachmentDaoUtil.get(attachId, Attachment.class);
	}
	

	@Override
	public File getAttachmentFile(Attachment att) {
		// TODO Auto-generated method stub
		if (fileStoreDir != null && att.getPath() != null) {
			String realpath = fileStoreDir + att.getPath();
			return new File(realpath);
		}
		return null;
	}
	
	public void removeFile(String path) {
		File file = new File(path);
		if (file.isFile())
			file.delete();
	}
	
	public void copy(File src, File dst) {
		try {
			InputStream in = null;
			OutputStream out = null;
			try {
				in = new BufferedInputStream(new FileInputStream(src),
						BUFFER_SIZE);
				out = new BufferedOutputStream(new FileOutputStream(dst),
						BUFFER_SIZE);
				byte[] buffer = new byte[BUFFER_SIZE];
				while (in.read(buffer) > 0) {
					out.write(buffer);
				}
			} finally {
				if (null != in) {
					in.close();
				}
				if (null != out) {
					out.close();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public String getExtention(String fileName) {
		int pos = fileName.lastIndexOf(".");
		return fileName.substring(pos);
	}

	public void copy(String src, String dst) {
		copy(new File(src), new File(dst));
	}

	public void copy(String src, File dst) {
		copy(new File(src), dst);
	}

	public void copy(File src, String dst) {
		copy(src, new File(dst));
	}
	

	@Resource
	public void setMailDaoUtil(DaoUtil<Mail> mailDaoUtil) {
		this.mailDaoUtil = mailDaoUtil;
	}

	@Resource
	public void setMailStateDaoUtil(DaoUtil<MailState> mailStateDaoUtil) {
		this.mailStateDaoUtil = mailStateDaoUtil;
	}

	@Resource
	public void setSendStateDaoUtil(DaoUtil<SendState> sendStateDaoUtil) {
		this.sendStateDaoUtil = sendStateDaoUtil;
	}

	@Resource
	public void setAttachmentDaoUtil(DaoUtil<Attachment> attachmentDaoUtil) {
		this.attachmentDaoUtil = attachmentDaoUtil;
	}

	@Resource
	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	@Resource
	public void setSendStateService(SendStateService sendStateService) {
		this.sendStateService = sendStateService;
	}

	@Resource
	public void setMailStateService(MailStateService mailStateService) {
		this.mailStateService = mailStateService;
	}

	
	

}
